home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-03 / qbpacket.zip / FRACTALS.BAS < prev    next >
BASIC Source File  |  1991-10-30  |  21KB  |  542 lines

  1. REM QBASIC FRACTAL EXPLORER (FRACTALS.BAS)
  2.  
  3. 'Subprogram declarations, generated automatically by QBasic
  4. DECLARE SUB DrawTriFract ()
  5. DECLARE SUB ShowFile ()
  6. DECLARE SUB ShowStats ()
  7. DECLARE SUB SaveCGA (FileName$)
  8. DECLARE SUB SaveEGA (FileName$)
  9. DECLARE SUB ShowCGA (FileName$)
  10. DECLARE SUB ShowEGA (FileName$)
  11. DECLARE SUB AnimateCGA ()
  12. DECLARE SUB AnimateEGA ()
  13. DECLARE SUB DrawFractal ()
  14. DECLARE SUB SetupCGA ()
  15. DECLARE SUB SetupEGA ()
  16. DECLARE SUB SetupMDA ()
  17. DECLARE SUB WaitKey ()
  18. DECLARE SUB SetImage ()
  19. DECLARE SUB SetSave ()
  20. DECLARE SUB SetFractal ()
  21. DECLARE SUB DoFractal ()
  22. DECLARE SUB SetScreen ()
  23. DECLARE SUB ShowMenu ()
  24. DECLARE SUB TextScreen ()
  25.  
  26. 'Constants to make loop tests more readable
  27. CONST True = -1
  28. CONST False = 0
  29.  
  30. ON ERROR GOTO HandleError:                             'Set up error trapping
  31.  
  32. TYPE ScreenType                         'Data type to hold screen information
  33.      Number AS INTEGER         'Number of screen to use with SCREEN statement
  34.      MaxColumns AS INTEGER                    'Maximum columns (X coordinate)
  35.      MaxRows AS INTEGER                          'Maximum rows (Y coordinate)
  36.      MaxColors AS INTEGER                                     'Maximum colors
  37.      Description AS STRING * 30                        'Description of screen
  38.      Extension AS STRING * 3         'Filename extension for this screen type
  39. END TYPE
  40.  
  41. MaxScreens% = 3                        'Number of different screens supported
  42. DIM Screens(1 TO MaxScreens%) AS ScreenType         'Holds ScreenType records
  43.  
  44. 'Read in the information for each screen supported
  45. FOR S = 1 TO MaxScreens%
  46.      READ Screens(S).Number
  47.      READ Screens(S).MaxColumns
  48.      READ Screens(S).MaxRows
  49.      READ Screens(S).MaxColors
  50.      READ Screens(S).Description
  51.      READ Screens(S).Extension
  52. NEXT S
  53. DATA 1,320,200,4, "CGA 320 x 200  4 colors","CGA"
  54. DATA 2,640,200,2, "MDA 640 x 200  2 colors","MDA"
  55. DATA 9,640,350,16,"EGA 640 x 350 16 colors","EGA"
  56.  
  57. 'Default initialization
  58. FractalType% = 1                                    'For Escape Time Fractals
  59. Mode% = 1                             'Screen mode; defaults to SCREEN 1, CGA
  60. Save% = False                          'Whether to save to disk after drawing
  61. SetupCGA                                       'Set up default CGA parameters
  62.  
  63. DoMenu:                                            'Label for ON ERROR resume
  64. ShowMenu                                       'This is the main program loop
  65. END
  66.  
  67. 'Error trapping routine
  68. HandleError:
  69.      ErrNum = ERR                         'Get error number from ERR function
  70.      SELECT CASE ErrNum                            'Print appropriate message
  71.           CASE IS = 53
  72.                PRINT "File not found.  Make sure you've typed"
  73.                PRINT "the name correctly."
  74.                WaitKey                 'Let user read message and press a key
  75.                RESUME NEXT                      'Loop back in calling routine
  76.           CASE IS = 64
  77.                PRINT "Bad file name.  Filenames may not have"
  78.                PRINT "more than 8 characters and a 3-character"
  79.                PRINT "extension."
  80.                WaitKey
  81.                RESUME NEXT
  82.           CASE IS = 71
  83.                PRINT "Disk error.  Make sure you have put a disk"
  84.                PRINT "in the drive and closed the drive door, if"
  85.                PRINT "necessary."
  86.                WaitKey
  87.                RESUME NEXT                      'Loop back in calling routine
  88.           CASE ELSE                            'Some other error has occurred
  89.                PRINT "Error number"; ErrNum; "has occurred"
  90.                WaitKey
  91.                RESUME DoMenu:   'Possibly serious error; so loop back to main
  92.                                                                         'menu
  93.      END SELECT
  94. END
  95.  
  96. SUB AnimateCGA
  97.      WHILE INKEY$ = ""                          'Run until user presses a key
  98.           COLOR , 0                                'Switch CGA palette colors
  99.           FOR P = 1 TO 1000                                      'Pause a bit
  100.           NEXT P
  101.           COLOR , 1                             'Switch back to first palette
  102.           FOR P = 1 TO 1000                                      'Pause again
  103.           NEXT P
  104.      WEND
  105. END SUB
  106.  
  107. SUB AnimateEGA                             'Animation (color cycling) for EGA
  108.      SHARED MaxColumns%, MaxRows%
  109.  
  110.      DIM Palettearray%(15)      'Set up the initial colors of the EGA palette
  111.      FOR Temp% = 0 TO 15
  112.           Palettearray%(Temp%) = Temp%'This will "flash" the screen colors of
  113.      NEXT                           'the fractal until the user presses a key
  114.      WHILE INKEY$ = ""
  115.           FOR Temp% = 0 TO 15    'Switch the EGA palette to successive colors
  116.                Palettearray%(Temp%) = Palettearray%(Temp%) + 1
  117.                IF Palettearray%(Temp%) > 63 THEN
  118.                     Palettearray%(Temp%) = Palettearray%(Temp%) - 64
  119.                END IF
  120.           NEXT
  121.           PALETTE USING Palettearray%(0)     'Rotate the colors on the screen
  122.      WEND
  123. END SUB
  124.  
  125. SUB DoFractal
  126.      SHARED Mode%, Save%, Time
  127.      CLS
  128.      SCREEN Mode%                         'Make sure we have the right screen
  129.      T1 = TIMER                                            'Set up for timing
  130.      IF Save% THEN
  131.           PRINT "Enter filename to save"
  132.           INPUT "(no extension)"; FileName$
  133.      END IF
  134.      CLS
  135.      DrawFractal                                  'Generate the fractal image
  136.      T2 = TIMER                                               'Stop the timer
  137.      Time = T2 - T1                                   'Calculate elapsed time
  138.      SELECT CASE Mode%'Choose correct animation routine for screen mode being
  139.                                                                         'used
  140.           CASE IS = 1, IS = 2         'Add more CASEs if you add screen modes
  141.                AnimateCGA
  142.           CASE IS = 9
  143.                AnimateEGA
  144.           CASE ELSE
  145.                PRINT "Unsupported video mode in subprogram DoFractal"
  146.      END SELECT
  147.  
  148.      IF Save% THEN                    'Did user turn on save to disk feature?
  149.           SELECT CASE Mode%      'If so, choose correct disk save routine for
  150.                CASE IS = 1, IS = 2                    'screen mode being used
  151.                     SaveCGA (FileName$)     'Add more CASEs if you add screen
  152.                                                                        'modes
  153.                CASE IS = 9
  154.                     SaveEGA (FileName$)
  155.                CASE ELSE
  156.                     LOCATE 22, 1
  157.                     PRINT "ERROR: Mode not defined for saving!"
  158.           END SELECT
  159.      END IF
  160. END SUB
  161.  
  162. SUB DrawFractal    'For Escape Time fractals substitute different formulas as
  163.                                                                      'desired
  164.      SHARED MaxColumns%, MaxRows%, Limit%, ColorDivisor%, FractalType%
  165.      FOR X1% = 1 TO MaxColumns%                              'For each column
  166.           FOR Y1% = 1 TO MaxColumns%                            'For each row
  167.                X = X1% / MaxColumns%            'Calculate initial comparison
  168.                Y = Y1% / MaxRows%                         'For column and row
  169.                Count% = 0                                'Start at count of 0
  170.                WHILE X * X + Y * Y <= Limit%'Until formulas pass cutoff point
  171.                     '--------------------------------------------------------
  172.                     '"Target" formulas for fractals.  Instead of the
  173.                     'following two lines, you can use other formulas.  Put a
  174.                     'REM or ' mark in front of other lines.
  175.                     '--------------------------------------------------------
  176.                     SELECT CASE FractalType%
  177.                          CASE IS = 1
  178.                               X = 2 * X                    '-----------------
  179.                               Y = 2 * Y                    '"Target" formulas
  180.                          CASE IS = 2                       '-----------------
  181.                               IF Y <= .5 THEN
  182.                                    IF X <= .5 THEN
  183.                                         X = 2 * X
  184.                                         Y = 2 * Y
  185.                                    ELSE X = 2 * X - 1
  186.                                         Y = 2 * Y
  187.                                    END IF
  188.                               ELSE
  189.                                    X = 2 * X
  190.                                    Y = 2 * Y - 1
  191.                               END IF
  192.                          CASE ELSE
  193.                               PRINT "Error in subprogram DrawFractal"
  194.                               WaitKey
  195.                               EXIT SUB
  196.                     END SELECT
  197.                     Count% = Count% + 1       'Keep track of number of passes
  198.                WEND                'When cutoff point reached, draw the point
  199.                PSET (X1%, Y1%), Count% \ ColorDivisor%
  200.                'SOUND 100 * Count%, 1                 'Optional sound effects
  201.                                                    'Use the appropriate color
  202.           NEXT                                               'Do the next row
  203.      NEXT                                                 'Do the next column
  204. END SUB
  205.  
  206. SUB SaveCGA (FileName$)
  207.      DEF SEG = &HB800                             'Switch to CGA video memory
  208.      BSAVE FileName$, 0, 16383                                'Save CGA image
  209.      DEF SEG                                  'Switch back to default segment
  210. END SUB
  211.  
  212. SUB SaveEGA (FileName$)
  213. '============================================================================
  214. 'Save EGA fractal image to disk--thanks to Ethan Winer of Crescent Software
  215. 'for this routine
  216. '============================================================================
  217.      DEF SEG = &HA000                             'Switch to EGA video memory
  218.      SIZE% = 28000                           'Each plane is 28,000 bytes long
  219.  
  220.      'Save blue plane
  221.      OUT &H3CE, 4
  222.      OUT &H3CF, 0
  223.      BSAVE FileName$ + ".BLU", 0, SIZE%
  224.      'Save green plane
  225.      OUT &H3CE, 4
  226.      OUT &H3CF, 1
  227.      BSAVE FileName$ + ".GRN", 0, SIZE%
  228.      'Save red plane
  229.      OUT &H3CE, 4
  230.      OUT &H3CF, 2
  231.      BSAVE FileName$ + ".RED", 0, SIZE%
  232.      'Save intensity plane
  233.      OUT &H3CE, 4
  234.      OUT &H3CF, 3
  235.      BSAVE FileName$ + ".INT", 0, SIZE%
  236.      OUT &H3CE, 4: OUT &H3CF, 0
  237.      DEF SEG                                  'Switch back to default segment
  238. END SUB
  239.  
  240. SUB SetFractal
  241.      SHARED FractalType%
  242.      CLS
  243.      PRINT "Set the type of fractal."
  244.      PRINT
  245.      PRINT "1. Escape Time Fractal"
  246.      PRINT "2. Triangular Fractal"
  247.      ValidFractal% = False
  248.      WHILE NOT ValidFractal%
  249.           PRINT "Enter selection or press Escape to exit"
  250.           F$ = INPUT$(1)
  251.           IF F$ = CHR$(27) THEN EXIT SUB
  252.           FractalType% = VAL(F$)
  253.           IF FractalType% < 1 OR FractalType% > 2 THEN
  254.                PRINT "Error in subprogram SetFractal: Invalid fractal type"
  255.           ELSE
  256.                ValidFractal% = True
  257.           END IF
  258.      WEND
  259. END SUB
  260.  
  261. SUB SetImage
  262.      SHARED MaxScreens%, Screens() AS ScreenType
  263.      SHARED Mode%, MaxColumns%, MaxRows%
  264.      FOR S = 1 TO MaxScreens%
  265.           IF Screens(S).Number = Mode% THEN        'Find out maximum rows and
  266.                ScrCols% = Screens(S).MaxColumns   'columns for current screen
  267.                ScrRows% = Screens(S).MaxRows                            'mode
  268.                Found = True
  269.                EXIT FOR
  270.           END IF
  271.      NEXT S
  272.      IF NOT Found THEN
  273.           PRINT "ERROR: Invalid screen in SetImage program!"
  274.           EXIT SUB
  275.      END IF
  276.  
  277.      CLS
  278.      PRINT "Set size of screen image."
  279.      PRINT "Number of columns (1 -"; ScrCols%; ")"
  280.      INPUT ImageCols%
  281.      IF ImageCols% < 1 OR ImageCols% > ScrCols% THEN     'Make sure number of
  282.           PRINT "Invalid number of columns"   'columns doesn't exceed maximum
  283.           WaitKey                                                 'for screen
  284.           EXIT SUB
  285.      END IF
  286.      PRINT "Number of rows (1 -"; ScrRows%; ")"
  287.      INPUT ImageRows%
  288.      IF ImageRows% < 1 OR ImageRows% > ScrRows% THEN  'Check rows in same way
  289.           PRINT "Invalid number of rows"
  290.           WaitKey
  291.           EXIT SUB
  292.      END IF
  293.      MaxColumns% = ImageCols%
  294.      MaxRows% = ImageRows%         'Set global variables for drawing routines
  295. END SUB
  296.  
  297. SUB SetSave                    'Turn on saving and get filename for next save
  298.      SHARED Save%           'Global variable will be used by drawing routimes
  299.      CLS
  300.      PRINT "Save is ";                           'Display current Save status
  301.      IF Save% THEN
  302.           PRINT "ON"
  303.      ELSE
  304.           PRINT "OFF"
  305.      END IF
  306.      PRINT
  307.      PRINT "Press any key to toggle Save Status"
  308.      PRINT "or Escape to leave: ";
  309.      PRINT
  310.      Status$ = INPUT$(1)
  311.      IF Status$ = CHR$(27) THEN                           'Escape was pressed
  312.           EXIT SUB
  313.      ELSE
  314.           Save% = NOT Save%'Toggle Save status to opposite state and show the
  315.           IF Save% THEN                                               'result
  316.                PRINT "Save is ON"
  317.           ELSE
  318.                PRINT "Save is OFF"
  319.           END IF
  320.           WaitKey
  321.      END IF
  322. END SUB
  323.  
  324. SUB SetScreen
  325.      SHARED Screens() AS ScreenType, MaxScreens%, Mode%
  326.      'Set screen mode
  327.      CLS
  328.      FOR S = 1 TO MaxScreens%       'List menu of available screens using the
  329.           PRINT Screens(S).Number;                             'Screens array
  330.           PRINT Screens(S).Description
  331.      NEXT S
  332.      PRINT "Type the number of the screen you want"
  333.      PRINT "or Escape to exit"
  334.      Scr$ = INPUT$(1)
  335.      IF Scr$ = CHR$(27) THEN EXIT SUB
  336.      Scr% = VAL(Scr$)
  337.      Found = False                          'Did user specify a valid screen?
  338.      FOR S = 1 TO MaxScreens%
  339.           IF Screens(S).Number = Scr% THEN
  340.                Found = True
  341.                EXIT FOR
  342.           END IF
  343.      NEXT S
  344.      IF Found THEN
  345.           Mode% = Scr%
  346.           SELECT CASE Mode%    'Choose proper initialization routine for this
  347.                CASE IS = 1                                            'screen
  348.                     SetupCGA
  349.                CASE IS = 2
  350.                     SetupMDA
  351.                CASE IS = 9
  352.                     SetupEGA
  353.                CASE ELSE
  354.                     PRINT "No code to set mode"; Mode%;
  355.                     PRINT "in subprogram SetScreen."
  356.           END SELECT
  357.           PRINT "Screen set to"; Mode%
  358.           WaitKey
  359.           EXIT SUB
  360.      ELSE                                     'Specified screen was not found
  361.           PRINT "Sorry! Screen number"; Scr%;
  362.           PRINT "is not supported."
  363.           WaitKey
  364.           EXIT SUB
  365.      END IF
  366. END SUB
  367.  
  368. SUB SetupCGA
  369.      SHARED MaxColumns%, MaxRows%, Limit%, ColorDivisor%
  370.      Limit% = 1500                                   'How far to test formula
  371.      ColorDivisor% = 4                           'Scale colors to CGA palette
  372.      MaxColumns% = 320      'Maximum values; SetImage routine can lower these
  373.      MaxRows% = 200                                                   'values
  374.      SCREEN 1                                      'CGA (320 x 200, 4 colors)
  375. END SUB
  376.  
  377. SUB SetupEGA
  378.      SHARED MaxColumns%, MaxRows%, Limit%, ColorDivisor%
  379.      Limit% = 200                                               'Cutoff point
  380.      ColorDivisor% = 1                            'Don't need to scale colors
  381.      MaxColumns% = 640      'Maximum values; SetImage routine can lower these
  382.      MaxRows% = 350                                                   'values
  383.      SCREEN 9                              'Hi-res EGA (640 x 350, 16 colors)
  384. END SUB
  385.  
  386. SUB SetupMDA
  387.      SHARED MaxColumns%, MaxRows%, Limit%, ColorDivisor%
  388.      Limit% = 3000
  389.      ColorDivisor% = 8
  390.      MaxColumns% = 640
  391.      MaxRows% = 200
  392.      SCREEN 2
  393. END SUB
  394.  
  395. SUB ShowCGA (FileName$)
  396.      SCREEN 1                                    'CGA 320 x 200, 4 color mode
  397.      CLS
  398.      DEF SEG = &HB800                             'Set to start of CGA memory
  399.      BLOAD FileName$    'Load file directly into screen memory to show image;
  400.      AnimateCGA                                     'then add special effects
  401.      DEF SEG                                         'Restore default segment
  402. END SUB
  403.  
  404. SUB ShowEGA (FileName$)
  405.      'Strip off the .EGA extension, since real files have four-color plane
  406.      'extensions
  407.      DotPos% = INSTR(FileName$, ".")
  408.      Name$ = LEFT$(FileName$, DotPos% - 1)
  409.      SCREEN 9                                    'EGA 640 x 350 16 color mode
  410.      CLS
  411.      DEF SEG = &HA000                             'Set to start of EGA memory
  412.  
  413.      'Manipulate EGA registers to load four planes from files
  414.      OUT &H3C4, 2
  415.      OUT &H3C5, 1
  416.      BLOAD Name$ + ".BLU", 0
  417.      OUT &H3C4, 2
  418.      OUT &H3C5, 2
  419.      BLOAD Name$ + ".GRN", 0
  420.      OUT &H3C4, 2
  421.      OUT &H3C5, 4
  422.      BLOAD Name$ + ".RED", 0
  423.      OUT &H3C4, 2
  424.      OUT &H3C5, 8
  425.      BLOAD Name$ + ".INT", 0
  426.      OUT &H3C4, 2
  427.      OUT &H3C5, 15
  428.      AnimateEGA                                  'Now add EGA special effects
  429.      DEF SEG                                         'Restore default segment
  430. END SUB
  431.  
  432. SUB ShowFile
  433.      SHARED MaxScreens%, Screens() AS ScreenType, Mode%
  434.  
  435.      'Show a fractal image from disk
  436.      'Calls specific routines for each screen type
  437.  
  438.      TextScreen                                          'Restore text screen
  439.      PRINT "Enter name of file to show, including extension"
  440.      INPUT FileName$
  441.      Ext$ = UCASE$(RIGHT$(FileName$, 3))
  442.      Found = False
  443.      FOR S = 1 TO MaxScreens%                     'Is this a valid extension?
  444.           IF Screens(S).Extension = Ext$ THEN
  445.                Found = True                           'Extension is supported
  446.           END IF
  447.      NEXT S
  448.      IF Found = False THEN                              'Extension is invalid
  449.           PRINT "Extension "; Ext$; " not supported"
  450.           EXIT SUB
  451.      ELSE
  452.           SELECT CASE Ext$                  'Call appropriate loading routine
  453.                CASE IS = "CGA", IS = "MDA"     'Fill in other CASEs as needed
  454.                     ShowCGA (FileName$)
  455.                CASE IS = "EGA"
  456.                     ShowEGA (FileName$)
  457.                CASE ELSE
  458.                     PRINT "Invalid extension "; Ext$
  459.           END SELECT
  460.      END IF
  461. END SUB
  462.  
  463. SUB ShowMenu
  464.      CONST MaxChoices% = 8                 'Change if you add more menu items
  465.      DIM Choices$(10)
  466.      Choices$(1) = "1) Set Screen Type"
  467.      Choices$(2) = "2) Set Image Size"
  468.      Choices$(3) = "3) Set Save Status"
  469.      Choices$(4) = "4) Generate Fractal Image"
  470.      Choices$(5) = "5) Show Fractal from Disk"
  471.      Choices$(6) = "6) Statistics on Last Image Generated"
  472.      Choices$(7) = "7) Set Fractal Type"
  473.      Choices$(8) = "8) Exit Fractal Explorer"
  474.  
  475.      WHILE True
  476.           TextScreen       'Start each time with normal 80 column text screen
  477.           PRINT "QBasic Fractal Explorer"
  478.           PRINT
  479.           FOR Choice = 1 TO MaxChoices%
  480.                PRINT Choices$(Choice)
  481.           NEXT Choice
  482.  
  483.           ValidChoice% = False
  484.           WHILE NOT ValidChoice%             'Loop until valid choice entered
  485.                PRINT "Press number between 1 and"; MaxChoices%
  486.                PRINT "or press"; MaxChoices%; "to end program"
  487.                Choice$ = INPUT$(1)
  488.                Choice% = VAL(Choice$)
  489.                IF Choice% = MaxChoices% THEN END
  490.                IF Choice% < 1 OR Choice% > MaxChoices% THEN
  491.                     BEEP
  492.                ELSE ValidChoice% = True
  493.                END IF
  494.           WEND
  495.           SELECT CASE Choice% 'Add more CASEs if you add features to the menu
  496.                CASE IS = 1
  497.                     SetScreen
  498.                CASE IS = 2
  499.                     SetImage
  500.                CASE IS = 3
  501.                     SetSave
  502.                CASE IS = 4
  503.                     DoFractal
  504.                CASE IS = 5
  505.                     ShowFile
  506.                CASE IS = 6
  507.                     ShowStats
  508.                CASE IS = 7
  509.                     SetFractal
  510.                CASE ELSE         'Doesn't hurt to prepare for the unexpected!
  511.                     PRINT "Error in menu setup"
  512.                     PRINT "Choice was: "; Choice%
  513.                     EXIT SUB
  514.           END SELECT
  515.      WEND
  516. END SUB
  517.  
  518. SUB ShowStats
  519.      SHARED Time                       'Value calculated in DoFractal routine
  520.      CLS
  521.      IF Time = 0 THEN
  522.           PRINT "No previous image generated this session."
  523.           WaitKey
  524.           EXIT SUB
  525.      END IF
  526.      PRINT "Last image took"; Time; "seconds."
  527.      WaitKey
  528. END SUB
  529.  
  530. SUB TextScreen
  531.      SCREEN 0                                         'Set normal text screen
  532.      WIDTH 80, 25               'Set width to 80 columns and clear the screen
  533.      CLS
  534. END SUB
  535.  
  536. SUB WaitKey
  537.      PRINT "Press any key to continue"
  538.      WHILE INKEY$ = ""                                'Loop until key pressed
  539.      WEND
  540. END SUB
  541.  
  542.